package com.gitee.wsl.collections.map.bikey

import com.gitee.wsl.func.Supplier
import com.gitee.wsl.func.consumer.BiConsumer
import com.gitee.wsl.func.consumer.Consumer
import com.gitee.wsl.func.consumer.TriConsumer
import kotlin.jvm.JvmOverloads

//class TableBiKeyMap<R, C, V> @JvmOverloads constructor(
//    innerMapSupplier: Supplier<out IntKeyMap<V>> // = Supplier { RadixTrie() }
//) : BiKeyMap<R, C, V>{
//    private val innerMapSupplier: Supplier<out IntKeyMap<V>>? = null
//    private var rows: Map<R, IntKeyMap<V>>? = null
//    private var columnsValues: List<C>? = null
//    private var columnIndex: Map<C, ColumnInfo>? = null
//    private var size = 0
//
//    init {
//        this.rows = HashMap()
//        this.columnsValues = ArrayList()
//        this.columnIndex = HashMap()
//        this.innerMapSupplier = innerMapSupplier
//    }
//
//    /**
//     * Constructs a new `TableBiKeyMap` with the same mappings as the
//     * specified `BiKeyMap`.
//     *
//     * @param m
//     * the map whose mappings are to be placed in this map
//     * @throws NullPointerException
//     * if the specified map is null
//     */
//    constructor(m: BiKeyMap<R, C, V>) : this() {
//        putAll(m)
//    }
//
//    public override fun put(row: R, column: C, value: V): V? {
//
//        val intMap: IntKeyMap<V> = rows.computeIfAbsent(row, { r -> innerMapSupplier!!.get() })
//        var columnInfo = columnIndex!![column]
//        if (columnInfo == null) {
//            columnInfo = ColumnInfo(columnsValues.size())
//            columnIndex.put(column, columnInfo)
//            columnsValues.add(column)
//        }
//        val prev: V? = intMap.put(columnInfo.index, value)
//        if (prev == null) {
//            size++
//            columnInfo.inc()
//        }
//        return prev
//    }
//
//    public override fun get(row: R, column: C): V? {
//
//        val columnInfo = columnIndex!![column]
//        if (columnInfo != null) {
//            val intMap: IntKeyMap<V?>? = rows!![row]
//            if (intMap != null) {
//                return intMap[columnInfo.index]
//            }
//        }
//        return null
//    }
//
//    public override fun remove(row: R, column: C): V? {
//        val columnInfo = columnIndex!!.get(column)
//        if (columnInfo != null) {
//            val intMap: IntKeyMap<V?>? = rows!!.get(row)
//            if (intMap != null) {
//                val prev: V? = intMap.remove(columnInfo.index)
//                if (prev != null) {
//                    size--
//                    if (intMap.isEmpty()) {
//                        rows.remove(row)
//                    }
//                    columnInfo.dec()
//                    if (columnInfo.count == 0) {
//                        columnsValues.set(columnInfo.index, null)
//                        columnIndex.remove(column)
//                    }
//                    return prev
//                }
//            }
//        }
//        return null
//    }
//
//    public override fun size(): Int {
//        return size
//    }
//
//    public override fun clear() {
//        rows.clear()
//        columnsValues.clear()
//        columnIndex.clear()
//        size = 0
//    }
//
//    /**
//     * Returns a shallow copy of this <tt>TableBiKeyMap</tt> instance: the
//     * elements themselves are not cloned.
//     *
//     * @return a shallow copy of this set
//     */
//    public override fun clone(): Any {
//        try {
//            val newMap = super.clone() as TableBiKeyMap<R?, C?, V?>
//            newMap.columnsValues = ArrayList(this.columnsValues)
//            newMap.columnIndex = HashMap(this.columnIndex.size())
//            this.columnIndex!!.forEach({ col, index ->
//                newMap.columnIndex.put(col, index.clone())
//            })
//            newMap.rows = HashMap(this.rows.size())
//            this.rows.forEach({ row, innerMap ->
//                val newOne: IntKeyMap<V?>? = innerMapSupplier!!.get()
//                newOne.putAll(innerMap)
//                newMap.rows.put(row, newOne)
//            })
//            return newMap
//        } catch (e: CloneNotSupportedException) {
//            throw InternalError(e)
//        }
//    }
//
//    public override fun containsValue(value: Any?): Boolean {
//        requireNonNull(value, "Value can not be null")
//        for (row in rows.values()) {
//            if (row.containsValue(value)) {
//                return true
//            }
//        }
//        return false
//    }
//
//    public override fun containsRow(row: R): Boolean {
//        val intKeyMap = rows!!.get(row)
//        return intKeyMap != null && intKeyMap.size() > 0
//    }
//
//    public override fun containsColumn(column: C): Boolean {
//        requireNonNull(column, "column can not be null")
//        val columnInfo = columnIndex!!.get(column)
//        return columnInfo != null && columnInfo.count > 0
//    }
//
//    public override fun keySet(): Set<BiKey<R?, C?>?>? {
//        return TableBiKeyMap.KeySet()
//    }
//
//    public override fun bikeySet(): BiKeySet<R?, C?> {
//        val result: BiKeySet<R?, C?> = TableBiKeySet()
//        forEachBiKey(result::add)
//        return result
//    }
//
//    public override fun values(): Collection<V?>? {
//        return TableBiKeyMap.Values()
//    }
//
//    public override fun rowKeySet(): Set<R?> {
//        return rows.keySet()
//    }
//
//    public override fun columnKeySet(): Set<C?> {
//        return columnIndex.keySet()
//    }
//
//    public override fun entrySet(): Set<BiKeyEntry<R?, C?, V?>?>? {
//        return TableBiKeyMap.EntrySet()
//    }
//
//    public override fun forEachBiKey(action: BiConsumer<in R?, in C?>) {
//        requireNonNull(action)
//        rows.entrySet().forEach{ entry ->
//            val intKeyMap: IntKeyMap<V?> = entry.getValue()
//            if (!intKeyMap.isEmpty()) {
//                val r: R? = entry.getKey()
//                intKeyMap.forEachKey{ key -> action.accept(r, columnsValues.get(key)) }
//            }
//        }
//    }
//
//    public override fun forEach(action: TriConsumer<in R?, in C?, in V?>) {
//        requireNonNull(action)
//        rows.entrySet().forEach({ entry ->
//            val intKeyMap: IntKeyMap<V?> = entry.getValue()
//            if (!intKeyMap.isEmpty()) {
//                val r: R? = entry.getKey()
//                intKeyMap.forEach({ idx, v -> action.accept(r, columnsValues.get(idx), v) })
//            }
//        })
//    }
//
//    public override fun iterator(): Iterator<BiKeyEntry<R?, C?, V?>?>? {
//        if (isEmpty()) {
//            return Collections.emptyIterator()
//        }
//        return TableBiKeyMap.BiKeyMapEntryIterator()
//    }
//
//    private inner class BiKeyMapIterator {
//        private val rowsIterator: Iterator<Entry<R?, IntKeyMap<V?>?>?> = rows.entrySet().iterator()
//        private var columnsIterator: Iterator<IntObjectEntry<V?>?>? = null
//
//        private var currentRow: R? = null
//
//        init {
//            moveToNextRow()
//        }
//
//        fun hasNextIt(): Boolean {
//            return columnsIterator != null && columnsIterator!!.hasNext()
//        }
//
//        fun nextIt(): BiKeyEntry<R?, C?, V?> {
//            val next: IntObjectEntry<V?> = columnsIterator!!.next()
//            val res: BiKeyEntry<R?, C?, V?> = TableBiKeyMap.SimpleBiKeyEntry<R?, C?, V?>(
//                currentRow, columnsValues.get(
//                    next.getIntKey()
//                ), next.getValue()
//            )
//            if (!columnsIterator!!.hasNext()) {
//                moveToNextRow()
//            }
//            return res
//        }
//
//        fun moveToNextRow() {
//            if (rowsIterator.hasNext()) {
//                val next: Entry<R?, IntKeyMap<V?>?> = rowsIterator.next()
//                currentRow = next.getKey()
//                columnsIterator = next.getValue().iterator()
//            } else {
//                columnsIterator = null
//            }
//        }
//    }
//
//    private inner class Values : AbstractCollection<V?>() {
//        public override fun size(): Int {
//            return this@TableBiKeyMap.size()
//        }
//
//        public override fun clear() {
//            this@TableBiKeyMap.clear()
//        }
//
//        public override fun iterator(): Iterator<V?>? {
//            if (isEmpty()) {
//                return Collections.emptyIterator()
//            }
//            return TableBiKeyMap.ValueIterator()
//        }
//
//        public override fun contains(o: Any?): Boolean {
//            return containsValue(o)
//        }
//
//        public override fun spliterator(): Spliterator<V?> {
//            return Spliterators.spliterator(
//                iterator(), size(),
//                Spliterator.DISTINCT + Spliterator.NONNULL + Spliterator.SIZED
//            )
//        }
//
//        public override fun forEach(action: Consumer<in V?>?) {
//            requireNonNull(action)
//            rows.values().forEach({ rowValue -> rowValue.values().forEach(action) })
//        }
//    }
//
//    private inner class KeySet : AbstractSet<BiKey<R?, C?>?>() {
//        public override fun size(): Int {
//            return this@TableBiKeyMap.size()
//        }
//
//        public override fun clear() {
//            this@TableBiKeyMap.clear()
//        }
//
//        public override fun iterator(): Iterator<BiKey<R?, C?>?>? {
//            if (isEmpty()) {
//                return Collections.emptyIterator()
//            }
//            return TableBiKeyMap.KeyIterator()
//        }
//
//        public override fun contains(o: Any?): Boolean {
//            requireNonNull(o, "Value can not be null")
//            val key: BiKey<R?, C?> = o as BiKey<R?, C?>
//            return containsKey(key.row, key.column)
//        }
//
//        public override fun spliterator(): Spliterator<BiKey<R?, C?>?> {
//            return Spliterators.spliterator(
//                iterator(), size(),
//                Spliterator.DISTINCT + Spliterator.NONNULL + Spliterator.SIZED
//            )
//        }
//
//        public override fun forEach(action: Consumer<in BiKey<R?, C?>?>) {
//            requireNonNull(action)
//            this@TableBiKeyMap.forEachBiKey(BiConsumer { r: R?, c: C? -> action.accept(BiKeyImpl(r, c)) })
//        }
//    }
//
//    private inner class EntrySet : AbstractSet<BiKeyEntry<R?, C?, V?>?>() {
//        public override fun size(): Int {
//            return this@TableBiKeyMap.size()
//        }
//
//        public override fun clear() {
//            this@TableBiKeyMap.clear()
//        }
//
//        public override fun iterator(): Iterator<BiKeyEntry<R?, C?, V?>?>? {
//            return this@TableBiKeyMap.iterator()
//        }
//
//        public override fun contains(o: Any?): Boolean {
//            requireNonNull(o, "Value can not be null")
//            val key: BiKeyEntry<R?, C?, V?> = o as BiKeyEntry<R?, C?, V?>
//            val value = get(key.row, key.column)
//            return (value != null && value == key.getValue())
//        }
//
//        public override fun spliterator(): Spliterator<BiKeyEntry<R?, C?, V?>?> {
//            return this@TableBiKeyMap.spliterator()
//        }
//
//        public override fun forEach(action: Consumer<in BiKeyEntry<R?, C?, V?>?>) {
//            this@TableBiKeyMap.forEach(TriConsumer { r: R?, c: C?, v: V? ->
//                action.accept(
//                    SimpleBiKeyEntry<R?, C?, V?>(
//                        r,
//                        c,
//                        v
//                    )
//                )
//            })
//        }
//    }
//
//    private inner class BiKeyMapEntryIterator : BiKeyMapIterator(), Iterator<BiKeyEntry<R?, C?, V?>?> {
//        public override fun hasNext(): Boolean {
//            return hasNextIt()
//        }
//
//        public override fun next(): BiKeyEntry<R?, C?, V?> {
//            return nextIt()
//        }
//    }
//
//    private inner class ValueIterator : BiKeyMapIterator(), Iterator<V?> {
//        public override fun hasNext(): Boolean {
//            return hasNextIt()
//        }
//
//        public override fun next(): V? {
//            return nextIt().getValue()
//        }
//    }
//
//    private inner class KeyIterator : BiKeyMapIterator(), Iterator<BiKey<R?, C?>?> {
//        public override fun hasNext(): Boolean {
//            return hasNextIt()
//        }
//
//        public override fun next(): BiKey<R?, C?> {
//            return nextIt()
//        }
//    }
//
//    override fun hashCode(): Int {
//        var h = 0
//        for (entry in entrySet()!!) {
//            h += entry.hashCode()
//        }
//        return h
//    }
//
//    override fun equals(o: Any?): Boolean {
//        if (o === this) {
//            return true
//        }
//
//        if (o !is BiKeyMap) {
//            return false
//        }
//        val m: BiKeyMap<R?, C?, V?> = o as BiKeyMap<R?, C?, V?>
//        if (m.size() !== size()) {
//            return false
//        }
//        try {
//            for (e in entrySet()!!) {
//                val row = e.row
//                val column = e.column
//                val value = e.getValue()
//                if (value != m.get(row, column)) {
//                    return false
//                }
//            }
//        } catch (unused: NullPointerException) {
//            return false
//        }
//        return true
//    }
//
//    override fun toString(): String {
//        val i = entrySet()!!.iterator()
//        if (!i.hasNext()) {
//            return "{}"
//        }
//        val sb = StringBuilder()
//        sb.append('{')
//        while (true) {
//            val e: BiKeyEntry<R?, C?, V?> = i.next()
//            val row: R? = e.row
//            val column: C? = e.column
//            val value: V? = e.getValue()
//            sb.append("[")
//            sb.append(if (row === this) "(this Map)" else row)
//            sb.append(',').append(' ')
//            sb.append(if (column === this) "(this Map)" else column)
//            sb.append("]")
//            sb.append('=')
//            sb.append(if (value === this) "(this Map)" else value)
//            if (!i.hasNext()) {
//                return sb.append('}').toString()
//            }
//            sb.append(',').append(' ')
//        }
//    }
//
//    private class ColumnInfo(private val index: Int) {
//        private var count = 0
//
//        fun inc() {
//            this.count++
//        }
//
//        fun dec() {
//            this.count--
//        }
//
//        public override fun clone(): ColumnInfo {
//            val newOne = ColumnInfo(this.index)
//            newOne.count = this.count
//            return newOne
//        }
//    }
//
//    internal class SimpleBiKeyEntry<R, C, V>(val row: R, val column: C, val value: V) : BiKeyEntry<R, C, V> {
//        val key: BiKey<R, C>
//            get() = BiKey(row, column)
//
//        /**
//         * Because IntObjectEntry has no reference to original map node, is not
//         * possible to modify its value.
//         *
//         * @param value
//         * new value to be stored in this entry
//         * @return old value corresponding to the entry
//         * @throws UnsupportedOperationException
//         * because it has no reference to original map
//         */
//        public override fun setValue(value: V): V? {
//            throw UnsupportedOperationException()
//        }
//
//        override fun hashCode(): Int {
//            val prime = 31
//            var result = prime + (if (column == null) 0 else column.hashCode())
//            result = prime * result + (if (row == null) 0 else row.hashCode())
//            result = prime * result + (if (value == null) 0 else value.hashCode())
//            return result
//        }
//
//        override fun equals(obj: Any?): Boolean {
//            if (this === obj) {
//                return true
//            }
//            if (obj == null) {
//                return false
//            }
//            if (javaClass != obj.javaClass) {
//                return false
//            }
//            val other: BiKeyEntry<*, *, *> = obj as BiKeyEntry<*, *, *>
//            if (row == null) {
//                if (other.row != null) {
//                    return false
//                }
//            } else if (row != other.row) {
//                return false
//            }
//            if (column == null) {
//                if (other.column != null) {
//                    return false
//                }
//            } else if (column != other.column) {
//                return false
//            }
//            if (value == null) {
//                if (other.getValue() != null) {
//                    return false
//                }
//            } else if (value != other.getValue()) {
//                return false
//            }
//            return true
//        }
//
//        fun toString(): String {
//            return "[$row, $column]=$value"
//        }
//    }
//}
